;Raj Akula
;CSC Project 1
;In each of the functions there is a listp which checks if the arguments is a list
;For start this is just so that i only pass lists to my add function 
;For add and multiply i check to see if i need to pass it recursively 
; to the opposite function like if its a list in that function 
; then it goes to the other list for example if its an add it goes to multiply
; if its a multiply it goes to add. Otherwise it just does the operations
;In the start i check isprime twice once for throwing it in the queue and the
; other so i can print if each element is a prime if i had them enclosed in the 
; same if then for some reason the one last is ignored... 


;this takes a list and breaks it down into sublists and also checks if each list is prime or not
(defun start(lis)
  (setf sum 0) ; variable for value of each list
  (setq foo '()) ;queue for all values
  (setq primenumbers '()) ; que for only primes
  (if (listp lis) ; checks if argument is infact a list
      (dolist (a lis) ; run through list of list in arguments
            (setf sum (add a)) ;calls add on the lists
            (if (isprime sum) ; checks for prime
                (push sum primenumbers)) ;if it is pushes into that queue
            (if (isprime sum) ; if it is prints its a prime
                (format t "~D is a prime! ~%" sum) )
              
            (if (not (isprime sum)) ; if its not prints not a prime
                (format t "~D is not a prime! ~%" sum))
	    (push sum foo) ; throws each sum into the all values queue 'foo'
        ))
  ;checks if everything is a prime or not and prints accordingly
  (if (equal foo primenumbers)  
    (print "All sets are prime!"  )
    )
  (if (not(equal foo primenumbers))
      (print "All sets are not prime!")
    )
  (return-from start "Done" )

)

;this list multiplies its list elements together if there is list inside the list it 
; calls the function add, and returns the result of the multiplication
(defun multiply(list)
  (setf result 1)
  (if (numberp list)
      (setf result (* result list)))
  (if (listp list)
      (dolist (a list)
        (if (numberp a)
            (setf result (* result a)))
        (if (listp a)
            (setf result (* result (add a))))
       )
  )
  (return-from multiply result)
)

;this list adds its list elements together if there is list inside the list it 
; calls the function multiply, and returns the result of the addition
(defun add(list)
  (setf sum 0)
  (if (numberp list)
      (setf sum (+ sum list)))
  (if (listp list)
      (dolist (a list)
        (if (numberp a)
            (setf sum (+ sum a)))
        (if (listp a)
            (setf sum (+ sum (multiply a))))
       )
  )
  (return-from add sum)
)
  
;this  checks if value passed in is a prime or not returns either a t for true or nil for false
; basically takes each prime square roots it and sees if any of the numbers between one
; and the square root divide into the argument... its a mathematical proof if its not a prime
; then there will be a number between 1 and sqrt(number) that divides into number!!
(defun isprime (x)
  (if (< x 2)
	  (return-from isprime nil)
	(dotimes (i (+ (ceiling (sqrt x)) 1))
	  (if (> i 1)
		  (if (< i x)
			  (if (equal (mod x i) 0)
				  (return-from isprime nil))))))
  (return-from isprime t)
)

  
